#ifndef __H_PS_TERRAIN__
#define __H_PS_TERRAIN__

#include "struct_define.fx"
#include "const_define.fx"

static const float BLEND_MAP_SIZE = 32.0f;
static const float T0 = 1.0f / BLEND_MAP_SIZE;
static const float DT = (BLEND_MAP_SIZE - 2.0f) / 16 / BLEND_MAP_SIZE;

texture texLayer1 = NULL;
texture texLayer2 = NULL;
texture texLayer3 = NULL;
texture texLayer4 = NULL;
texture texBlendWeight = NULL;
texture texShadowMap = NULL;
texture texLightMap = NULL;

sampler SamplerLayer1 = 
sampler_state
{
	Texture = <texLayer1>;
	AddressU = Wrap;
	AddressV = Wrap;
	MipFilter = Linear;
	MinFilter = Linear;
	MagFilter = Linear;
};

sampler SamplerLayer2 = 
sampler_state
{
	Texture = <texLayer2>;
	AddressU = Wrap;
	AddressV = Wrap;
	MipFilter = Linear;
	MinFilter = Linear;
	MagFilter = Linear;
};


sampler SamplerLayer3 = 
sampler_state
{
	Texture = <texLayer3>;
	AddressU = Wrap;
	AddressV = Wrap;
	MipFilter = Linear;
	MinFilter = Linear;
	MagFilter = Linear;
};


sampler SamplerLayer4 = 
sampler_state
{
	Texture = <texLayer4>;
	AddressU = Wrap;
	AddressV = Wrap;
	MipFilter = Linear;
	MinFilter = Linear;
	MagFilter = Linear;
};

sampler SamplerBlendWeight = 
sampler_state
{
	Texture = <texBlendWeight>;
	AddressU = Wrap;
	AddressV = Wrap;
	MipFilter = Linear;
	MinFilter = Linear;
	MagFilter = Linear;
};

sampler SamplerShadow = sampler_state
{
	texture = <texShadowMap>;
	AddressU = Border;
	AddressV = Border;
	BorderColor = 0xffffffff;
	MipFilter = Linear;
	MinFilter = Linear;
	MagFilter = Linear;
};

sampler SamplerLightMap = sampler_state
{
	texture = (texLightMap);
	AddressU = Mirror;
	AddressV = Mirror;
	MipFilter = Linear;
	MinFilter = Linear;
	MagFilter = Linear;
};

//////////////////////////////////////////////////
// normal terrain.
PSO PS_TERRAIN_1(VSO_TERRAIN IN)
{
	PSO OUT;
	float2 uv = IN.texCoord * 0.5f;
	float4 tex1 = tex2D(SamplerLayer1, uv);
	float4 specular = CalcSpecularLookDir(IN.lookDir, IN.normal, specularLight, shinness);
	float4 light = ambientLight + IN.diffuse + specular;
	OUT.color = tex1 * light;
	return OUT;
}

PSO PS_TERRAIN_2(VSO_TERRAIN IN)
{
	PSO OUT;
	float2 uvBlend = float2(IN.texCoord.x * DT + T0, IN.texCoord.y * DT + T0);
	float4 blendColor = tex2D(SamplerBlendWeight, uvBlend);
	float2 uv = IN.texCoord * 0.5f;
	float4 tex1 = tex2D(SamplerLayer1, uv) * blendColor.r;
	float4 tex2 = tex2D(SamplerLayer2, uv) * blendColor.g;
	float4 specular = CalcSpecularLookDir(IN.lookDir, IN.normal, specularLight, shinness);
	float4 light = ambientLight + IN.diffuse + specular;
	OUT.color = (tex1 + tex2) * light;
	return OUT;
}


PSO PS_TERRAIN_3(VSO_TERRAIN IN)
{
	PSO OUT;
	float2 uvBlend = float2(IN.texCoord.x * DT + T0, IN.texCoord.y * DT + T0);
	float4 blendColor = tex2D(SamplerBlendWeight, uvBlend);
	float2 uv = IN.texCoord * 0.5f;
	float4 tex1 = tex2D(SamplerLayer1, uv) * blendColor.r;
	float4 tex2 = tex2D(SamplerLayer2, uv) * blendColor.g;
	float4 tex3 = tex2D(SamplerLayer3, uv) * blendColor.b;
	float4 specular = CalcSpecularLookDir(IN.lookDir, IN.normal, specularLight, shinness);
	float4 light = ambientLight + IN.diffuse + specular;
	OUT.color = (tex1 + tex2 + tex3) * light;
	return OUT;
}

PSO PS_TERRAIN_4(VSO_TERRAIN IN)
{
	PSO OUT;
	float2 uvBlend = float2(IN.texCoord.x * DT + T0, IN.texCoord.y * DT + T0);
	float4 blendColor = tex2D(SamplerBlendWeight, uvBlend);
	float2 uv = IN.texCoord * 0.5f;
	float4 tex1 = tex2D(SamplerLayer1, uv) * blendColor.r;
	float4 tex2 = tex2D(SamplerLayer2, uv) * blendColor.g;
	float4 tex3 = tex2D(SamplerLayer3, uv) * blendColor.b;
	float4 tex4 = tex2D(SamplerLayer4, uv) * blendColor.a;
	float4 specular = CalcSpecularLookDir(IN.lookDir, IN.normal, specularLight, shinness);
	float4 light = ambientLight + IN.diffuse + specular;
	OUT.color = (tex1 + tex2 + tex3 + tex4) * light;
	return OUT;
}

/////////////////////////////////////////////////////
// normal terrain + fog.
PSO PS_TERRAIN_FOG_1(VSO_TERRAIN_FOG IN)
{
	PSO OUT;
	float2 uv = IN.texCoord * 0.5f;
	float4 tex1 = tex2D(SamplerLayer1, uv);
	float4 specular = CalcSpecularLookDir(IN.lookDir, IN.normal, specularLight, shinness);
	float4 light = ambientLight + IN.diffuse + specular;
	float4 color = tex1 * light;
	OUT.color = lerp(color, fogColor, IN.fog);
	return OUT;
}

PSO PS_TERRAIN_FOG_2(VSO_TERRAIN_FOG IN)
{
	PSO OUT;
	float2 uvBlend = float2(IN.texCoord.x * DT + T0, IN.texCoord.y * DT + T0);
	float4 blendColor = tex2D(SamplerBlendWeight, uvBlend);
	float2 uv = IN.texCoord * 0.5f;
	float4 tex1 = tex2D(SamplerLayer1, uv) * blendColor.r;
	float4 tex2 = tex2D(SamplerLayer2, uv) * blendColor.g;
	float4 specular = CalcSpecularLookDir(IN.lookDir, IN.normal, specularLight, shinness);
	float4 light = ambientLight + IN.diffuse + specular;
	float4 color = (tex1 + tex2) * light;
	OUT.color = lerp(color, fogColor, IN.fog);
	return OUT;
}


PSO PS_TERRAIN_FOG_3(VSO_TERRAIN_FOG IN)
{
	PSO OUT;
	float2 uvBlend = float2(IN.texCoord.x * DT + T0, IN.texCoord.y * DT + T0);
	float4 blendColor = tex2D(SamplerBlendWeight, uvBlend);
	float2 uv = IN.texCoord * 0.5f;
	float4 tex1 = tex2D(SamplerLayer1, uv) * blendColor.r;
	float4 tex2 = tex2D(SamplerLayer2, uv) * blendColor.g;
	float4 tex3 = tex2D(SamplerLayer3, uv) * blendColor.b;
	float4 specular = CalcSpecularLookDir(IN.lookDir, IN.normal, specularLight, shinness);
	float4 light = ambientLight + IN.diffuse + specular;
	float4 color = (tex1 + tex2 + tex3) * light;
	OUT.color = lerp(color, fogColor, IN.fog);
	return OUT;
}

PSO PS_TERRAIN_FOG_4(VSO_TERRAIN_FOG IN)
{
	PSO OUT;
	float2 uvBlend = float2(IN.texCoord.x * DT + T0, IN.texCoord.y * DT + T0);
	float4 blendColor = tex2D(SamplerBlendWeight, uvBlend);
	float2 uv = IN.texCoord * 0.5f;
	float4 tex1 = tex2D(SamplerLayer1, uv) * blendColor.r;
	float4 tex2 = tex2D(SamplerLayer2, uv) * blendColor.g;
	float4 tex3 = tex2D(SamplerLayer3, uv) * blendColor.b;
	float4 tex4 = tex2D(SamplerLayer4, uv) * blendColor.a;
	float4 specular = CalcSpecularLookDir(IN.lookDir, IN.normal, specularLight, shinness);
	float4 light = ambientLight + IN.diffuse + specular;
	float4 color = (tex1 + tex2 + tex3 + tex4) * light;
	OUT.color = lerp(color, fogColor, IN.fog);
	return OUT;
}

#endif // __H_PS_TERRAIN__